無法在 Access 中強制執行參照完整性 (unable to enforce referential integrity in Access)


問題描述

無法在 Access 中強制執行參照完整性 (unable to enforce referential integrity in Access)

I've checked everything for errors: primary key, uniqueness, and type. Access just doesnt seem to be able to link the 2 fields i have in my database. can someone please take a look?

http://www.jpegtown.com/pictures/jf5WKxKRqehz.jpg

Thanks.


參考解法

方法 1:

Your relationship diagram shows that you've made the ID fields your primary key in all your tables, but you're not using them for your joins. Thus, they serve absolutely no purpose. If you're not going to use "surrogate keys" (i.e., a meaningless ID number that is generated by the database and is unique to each record, but has absolutely no meaning in regard to the data in your table), then eliminate them. But if you're going to use "natural keys" (i.e., a primary key constructed from a set of real data fields that together are going to be unique for each record), you must have a unique compound index on those fields.

However, there are issues with both approaches:

  1. Surrogate Keys: a surrogate PK makes each record unique. That is you could have a record for David Fenton with ID 1 and a record for David Fenton with ID 2. If it's the same David Fenton, you've got duplicate data, but as far as your database knows, they are unique. 

  2. Natural Keys: some types of entities work very well with natural keys. The best such are where there's a single field that identifies the record uniquely. An example would be "employee type," where values might be "associate, manager, etc." In that case, it's a very good candidate for using the natural key instead of adding a surrogate key. The only argument against the natural key in that case is if the data in the candidate natural key is highly volatile (i.e., it changes frequently). While every modern database engine provides "CASCADE UPDATE" functionality (i.e., if the value in the PK field changes, all the tables where that field is a Foreign Key are automatically updated), this imposes a certain amount of overhead and can be problematic. For single-column keys, it's unlikely to be an issue. Now, except for lookup tables, there are very few entities for which a natural key will be a single column. Instead, you have to create a compound index, i.e., an index that spans multiple data fields. In the index dialog in Access table design, you create a compound key by giving it a name in the first column, and then adding multiple rows in the second column (from the dropdown list of fields in your table). The drawback of this is that if any of the fields in your compound unique index are unknown, you won't get uniqueness. That is, if a field has a Null in two records, and the rest of the fields are identical, this won't be counted as a conflict of uniqueness because Null never equals Null. This is because Null doesn't mean "empty" -- it means "Unknown."

Allen Browne has explained everything you need to know about Nulls:

  • Nulls: Do I Need Them?
  • Common Errors with Null

In your graphic, you show that you are trying to link the Company table with the PManager table. The latter table has a CompanyID field, and your Company table has a unique index on its ID field, so all you need is a link from the ID field of the Company table to the CompanyID field of the PManager table. For your example to work (which would be useless, since you already have a unique index on the ID field), you'd need to create a unique compound key spanning both ID and ShortName in the Company table. 

Additionally, if ShortName is a field that you want to be unique (i.e., you don't want two company records to have the same ShortName), you should add a unique index to it, whether or not you still use the ID field as your primary key. This brings me back to item #1 above, where I described a situation where a surrogate key could lead you to enter duplicate records, because uniqueness is established by the surrogate key along. Any time you choose to use a surrogate key, you must also add a unique compound index on any combination of data fields that needs to be unique (with the caveat about Null fields as outlined in item #2).

If you're thinking "surrogate keys mean more indexes" you're correct, in that you have two unique indexes on the same table (assuming you don't have the Null problem). But you do get substantial ease of use in joining tables in SQL, as well as substantially less duplication of data. Likewise, you avoid the overhead of CASCADE UPDATE. On the other hand, if you're viewing a child table with a natural foreign key, you don't need to join to the parent table to be able to identify the parent record, because the data that identifies that record is right there in the foreign-key fields. That lack of a need for a join can be a major performance gain in certain scenarios (especially for the case where you'd need an outer join because the foreign key can be Null).

This is actually quite a huge topic, and it's something of a religious argument. I'm firmly in the surrogate key camp, but I use natural keys for lookup tables where the key is a single column. I don't use natural keys for any other purpose. That said, where possible (i.e., no Null problems) I also have a unique index on the natural key.

Hope this helps.

方法 2:

Actually you need an index on the name fields, on both sides

However, may I suggest that you have way too many joins?  In general there should only be one join from one table to the next.  It is rare to have more than one join between tables, and exceedingly rare to have more than two.

Have a look at this link: http://weblogs.asp.net/scottgu/archive/2006/07/12/Tip_2F00_Trick_3A00_-Online-Database-Schema-Samples-Library.aspx

Notice how all of the tables are joined together by a single relationship?

Each of the fields labeled PK are primary keys.  These are AUTONUMBER fields.  Each of the fields labeled FK are foreign keys.  These are indexed Number fields of type Integer.  The Primary Keys are connected to the Foreign Keys in a 1 to many relationship (in most cases).

99% of the time, you won't need any other kind of joins.  The trick is to create tables with unique information.  There is a lot of repeated information in your database.

A database that is reorganized in this manner is called a "normalized" database.  There are lots of good examples of these at http://www.databaseanswers.org/data_models/

方法 3:

Just join on the CompanyID. You could also get rid of the Company field in PManager.

方法 4:

I did the following and the problem was solved (I face the same problem of referential integrity in access).

  1. I exported data from both tables in Access to Excel. Table1 was containing Cust Code and basic information about the company. Cust Code as Primary key.

  2. Table2 was containing all information about who the customers associated with that company.

  3. I removed all duplicates from Table2 exported to excel.

  4. Using Vlookup I checked and found that there are 11 customers code not present in Table1.

  5. I added those codes in Access Table. I linked by referential integrity and Problem was solved.

Also look for foreign key if it does not work.

(by Tam N.David-W-FentonRobert HarveyJeffOAshirwad Patil)

參考文件

  1. unable to enforce referential integrity in Access (CC BY-SA 3.0/4.0)

#referential-integrity #ms-access






相關問題

Jika saya memiliki batasan kunci asing dari tabel itu sendiri, apakah saya perlu berhati-hati saat menghapus seluruh tabel? (If I have a foreign key constraint of a table to itself, do I need to be careful when deleting the whole table?)

如何檢查我是否只刪除了所需的數據? (How do I check that I removed required data only?)

如何在 Postgres 8.2 中禁用參照完整性? (How do I disable referential integrity in Postgres 8.2?)

Xóa phụ huynh nếu nó không được tham chiếu bởi bất kỳ đứa trẻ nào khác (Delete parent if it's not referenced by any other child)

Có cách nào để kiểm tra tính toàn vẹn của tham chiếu cho các bảng MyIsam bằng cách sử dụng quan hệ gốc YII không? (Is there a way to check referential integrity for MyIsam tables using YII native relations?)

ActiveDirectoryMembershipProvider 和參照完整性 (ActiveDirectoryMembershipProvider and referential integrity)

SQL2005:將一個錶鍊接到多個表並保留Ref Integrity? (SQL2005: Linking a table to multiple tables and retaining Ref Integrity?)

違反完整性約束 - 調用存儲過程時未找到父鍵 (Integrity constraint violated - parent key not found when calling stored procedure)

db2 參照完整性問題 (db2 referential integrity problem)

無法在 Access 中強制執行參照完整性 (unable to enforce referential integrity in Access)

破壞的參照完整性:埃德加科德會說什麼? (Broken referential integrity: What would Edgar Codd say?)

如何更新鏈接到多個表的 FK - 更新時的級聯 (How to update FK linked to multiple table - Cascade on Update)







留言討論